package controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import entity.IData;

public class RemoteController implements Runnable, IRemoteController {

	private IData data;
	private Socket clientSocket;
	private IMenuController mc;

	public RemoteController(IData data, Socket clientSocket, IMenuController mc){
		this.data = data;
		this.clientSocket = clientSocket;
		this.mc = mc;
	}

	@Override
	public void run() {
		mc.connected(clientSocket.getInetAddress().toString() + " - port: " + clientSocket.getPort());	
		try ( 	PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
				BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
				){
			boolean connected = true;
			while(connected){
				String returnTxt;
				String clientData = in.readLine();

				if (clientData == null){
					connected = false;
					mc.unConnected(clientSocket.getInetAddress().toString() + " Port: " + clientSocket.getPort());
					clientSocket.close();
				} else {
					data.setDebug1(clientData);
					//Afvejning
					if (clientData.length()==1 && clientData.charAt(0)=='S'){
						returnTxt=getBrutto();
					}
					//Tara
					else if (clientData.length()==1 && clientData.charAt(0)=='T'){
						returnTxt=taraWeigth();
					}
					//Slet vægtens display - reset evt skreven tekst så der kun vises vægt
					else if (clientData.length()==2 && clientData.charAt(0)=='D' && clientData.charAt(1)=='W'){
						returnTxt=resetDisplay();
					}
					//Skriv i vægtens display
					else if (clientData.length()>=3 && clientData.charAt(0)=='D' && clientData.charAt(2)=='"'){
						int m=0;
						for(int i=0; i<clientData.length(); i++){
							if(clientData.charAt(i)=='"'){
								m++;
							}
						}
						if(m==2){
						returnTxt=writeInDisplay(clientData);
						} else{
							returnTxt="D L";
						}
					}
					//P111 - skriv maks 30 tegn i display
					else if (clientData.length()>=7 && clientData.charAt(0)=='P' && clientData.charAt(1)=='1' && clientData.charAt(2)=='1' && clientData.charAt(3)=='1' && clientData.charAt(5)=='"'){
						int m=0;
						for (int i=0; i<clientData.length(); i++){
							if(clientData.charAt(i)=='"'){
								m++;
							}
						}
						if(m==2){
							returnTxt=p111(clientData);							
						} else{
							returnTxt="P111 L";
						}
					}
					//RM20_8
					else if (clientData.length()>7 && clientData.charAt(0)=='R' && clientData.charAt(1)=='M' && clientData.charAt(2)=='2' && clientData.charAt(3)=='0' && clientData.charAt(5)=='8' && clientData.charAt(7)=='"'){
						int i;
						int m=0;
						for (i=0;i<clientData.length();i++){ //Tjekker om RM20 kommando indeholder 3 sæt "".
							if(clientData.charAt(i)=='"'){
								m++;
							}
						}
						if(m==6 && rm20_8(clientData)){ //Hvis der er talt 6 " tegn, så er RM20 kommandoen godkendt
							out.println("RM20 B"); //Første output til brugeren (kommando modtaget)
							data.setDebug2("RM20 B");
							returnTxt= "RM20 A " + "\""+ mc.showRM20() + "\""; //Andet output til brugeren (Tekst fra operatør)
						} else{
							returnTxt="RM20 L";
						}
					}
					else{						
						returnTxt="ES";
					}
					out.println(returnTxt); 
					data.setDebug2(returnTxt);
				}
			}			
		} catch (IOException e) {
			mc.unConnected(clientSocket.getInetAddress().toString());
			e.printStackTrace();
		}
	}

	//D - kommando
	@Override
	public String writeInDisplay(String clientData){
		String output;
		String sString = clientData.substring(3,clientData.length()-1);
		if(sString.length()>7){
			output="D L"; //Fejlmeddelelse
		} else{
			output="D A"; //Input OK
			data.setDebug2(output);
			data.setDisplay(sString);
			mc.upDisplay(true);
		}
		return output;
	}

	//S kommando (Afvejning)
	@Override
	public String getBrutto(){
		String output;
		output="S S      " + String.format("%.4f", data.getWeight()-data.getTaraWeight())+" kg";
		data.setDebug2(output);
		mc.upDisplay(false);
		return output;
	}

	//T kommando (tara vægt)
	@Override
	public String taraWeigth(){
		String output;
		data.setTaraWeight(data.getWeight());
		output="T S     " + Double.toString(data.getTaraWeight()); //Svar til klienten.
		data.setDebug2(output);
		mc.upDisplay(false);
		return output;
	}

	//DW kommando (Slet vægtens display / reset display)
	@Override
	public String resetDisplay(){
		String output;
		data.setDisplay(null);
		output="DW A"; //Svar til klienten
		data.setDebug2(output);
		mc.resetDisplay();
		return output;
	}

	//P111 kommando (skriv maks 30 tegn i display)
	@Override
	public String p111(String clientData){
		String output;
		String sString = clientData.substring(6, clientData.length()-1);
		if (sString.length() > 30){
			output="P111 L";
		} else{
			data.setP111(sString);
			output="P111 A";
			data.setDebug2(output);
			mc.upDisplay(false);
		}
		return output;
	}

	//RM20 8 kommando
	@Override
	public boolean rm20_8(String clientData){
		String sString1, sString2, sString3;
		//Leder efter første sub-string
		int o = 7;
		int end = findSubString(o, clientData);
		sString1 = clientData.substring(o+1, end);
		if(sString1.length()>24){
			return false;
		}

		//Leder efter anden sub-string
		o = end +2; 
		if (o+2 <= clientData.length() && clientData.charAt(o) == '"'){
		end = findSubString(o, clientData);
		sString2 = clientData.substring(o+1, end);
		if(sString2.length()>21){
			return false;
		}
		} else return false;

		//Leder efter tredje substring
		o = end +2;
		if (o+2 <= clientData.length() &&  +clientData.charAt(o) == '"'){
		end = findSubString(o, clientData);
		sString3 = clientData.substring(o+1, end);
		if(sString3.length()>7){
			return false;
		}
		} else return false;

		data.setRM20(sString1, sString2, sString3);
		return true; 
	}
	
	private int findSubString(int start, String clientData){
		if(clientData.charAt(start) == '"' && clientData.charAt(start+1)=='"'){
			return start+1;
		} else{
			int p = start+1;
			do{
				p++;
			} while(clientData.charAt(p)!='"');
			return p;
		}
	}
}
